#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <stdbool.h>
#include <pthread.h>

#include <time.h>
#include <sqlite3.h>

#include "zlog.h"
#include "cjson/cJSON.h"
#include "ds18b20.h"
#include "database.h"
#include "yuyv2bmp.h"
#include "get_smoke.h"
#include "put_voice.h"

#define SERVER_IP          "192.168.1.131"
#define SERVER_PORT        8889
#define MSG_STR            "Hello world!"

int socket_connect(char *ip, int port);
int pack_json(char *buf,double temp,time_t tm, int smoke);
void *set_file(void *arg);

int    g_sign_run= 1;
int    g_conn_file = 0;
int    g_video = 0;

void signal_run(int signum)
{
    if(signum == SIGINT)
    {
        g_sign_run = 0;

    }
}





int main(int argc, char **argv)
{

	//sokcet connect
	int                     connected = 0;
	int                     conn_fd;
	int                     rv = -1;

	//temp 
	int                     temp_true = 0;
	double                  temp;
	char                    buf[1024]; 

	//time
	int                     tim;
	time_t                  tm;
	time_t                  last_time = 0;
	time_t                  curr_time;

	//sqlite 
	int                     i;
	int                     number;
	int                     rowid;
	sqlite3                 *db = NULL;

	// smoke
	int                     rc;
	int                     smoke;


	// pthread
	pthread_t               tid;

	int                    read_buf[64];
	int                    readc;




	//software interrupt
	signal(SIGINT,signal_run);

	//Log Initialization
	rc = dzlog_init("zlog_conf","class");
	if(rc)
	{   
		printf("zlog_init false\n");
		zlog_fini();
		return -1; 
	}

	dzlog_info("zlog init successfully\n");


	open_database(&db,0);

	//Run when no terminating signal is received
	while(g_sign_run)
	{
		temp_true = 0;
		//Data is collected every 30 seconds
		time(&curr_time);
		if((curr_time - last_time) > 5)
		{
			ds18b20_get_temperature(&temp);
			smoke = get_smoke();
			if(g_video < 1)
			{
				yuyv2bmp();
				g_video++ ;
			}
			time(&tm);
			memset(buf, 0, sizeof(buf));
			pack_json(buf,temp,tm,smoke);
			temp_true = 1;

			last_time =curr_time;

		}
		if(temp_true)
		{
			pthread_attr_t attr;			/*通过线程属性来设置游离态*/
			pthread_attr_init(&attr);
			pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
			rv = pthread_create(&tid, &attr, set_file, NULL);
			if(rv < 0) 
			{
				dzlog_error("fork() create child process failure : %s\n",strerror(errno));
				continue;
			}
			else 
			{
				if( !connected )
				{

					conn_fd = socket_connect(SERVER_IP, SERVER_PORT);
					if(conn_fd < 0)
					{
						if(temp_true)
						{
							insert_data(db,tm,temp,smoke);
							temp_true = 0;
						}
						connected = 0;
						sleep(3);
						continue;
					}
					else
					{
						connected = 1;
					}
				}
				else if(connected)
				{
					dzlog_info("JSON String: %s\n", buf);
					rv = write(conn_fd, buf, strlen(buf));
					if( rv <= 0 )
					{
						dzlog_error("Write data to server failure: %s", strerror(errno));
						insert_data(db,tm,temp,smoke);
						connected = 0;
					}
					else if(rv > 0)
					{
						dzlog_info("send data over");
						sleep(5);
					}

					number = get_table(db);
					if(number <= 0)
					{
						dzlog_warn("There is no data in the database!\n");
						sqlite3_close(db);
						sleep(5);
						continue;
					}

					dzlog_info("the database have %d rows of data\n",number);


					number = number<10 ? number:10 ;

					i = 0;

					while(i < number)
					{
						get_data(db, &tim, &temp, &rowid,&smoke);
						tm = (time_t)tim;
						pack_json(buf,temp,tm,smoke);
						dzlog_info("JSON String: %s\n", buf);
						if((rv = write(conn_fd, buf, strlen(buf))) <= 0 )
						{
							dzlog_error("Write data to server [%s:%d] failure: %s\n", SERVER_IP, SERVER_PORT, strerror(errno));
							continue;
						}
						else if (rv >0)
						{

							dzlog_info("The data in the database send over\n");
							delete_data(db,rowid);
						}

						i++;
					}
			//		memset(read_buf,0,sizeof(read_buf));
			//		readc = read(conn_fd,read_buf,128);
			//		if(readc > 0)
			//		{
			//			buzzer_low(read_buf);
			//		}

			//		printf("I geted message %d bytes,%s\n",readc,read_buf);
				}
			}
		}
	}
cleanup:

	close(conn_fd);

	return 0;
}


int socket_connect(char *ip, int port)
{
	int                     sockfd;
	struct sockaddr_in      serv_addr;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if(sockfd < 0)
	{
		dzlog_error("create socket failure: %s\n\n", strerror(errno));
		return -1;
	}

	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_port = htons(port);
	inet_aton( ip, &serv_addr.sin_addr );

	if( connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr))  < 0)
	{
		//dzlog_error("connect to server [%s:%d] failure: %s\n", ip, port, strerror(errno));
		close(sockfd);
		return -2;
	}

	dzlog_info("connect to server [%s:%d] successfully\n\n", ip, port);
	return sockfd;
}

void *set_file(void *arg)
{
	int                     conn_file_fd;
	int                     conn_file = 0;
	FILE *                  read;
	int                     rw;
	FILE *                  fps;
	int                     file_size;
	char                    file_buff[2048];
	int                     size;
	int                     ret;

	while( !conn_file )
	{

		conn_file_fd = socket_connect(SERVER_IP, 8888);
		if(conn_file_fd < 0)
		{
			conn_file = 0;
			sleep(3);
		}
		else
		{
			conn_file = 1;
		}
	}
	//open pictrue file
	fps = fopen("my.bmp","r");
	if(!fps)
	{
		dzlog_error("open file failure! %s\n",strerror(errno));
	}

	memset(file_buff,0,sizeof(file_buff)); 
	while((size = fread(file_buff,1,1024,fps)) > 0)
	{
	     ret = write(conn_file_fd,file_buff,size);
	     if(ret < 0)
	     {
		     dzlog_error("write picture  fail %s!\n",strerror(errno));
		     conn_file = 0;
		     break;

	     }

	}
	if(size < 0)
	{
		dzlog_error("read fail!\n");
	}
	dzlog_info("write pictrue successful!\n");
	fclose(fps);
	close(conn_file_fd);

}


int pack_json(char *buf, double temp, time_t tm, int  smoke)
{
	if(!temp||!tm||!buf)
	{
		dzlog_error("wrong parameter! \n");
		return -1;
	}
	cJSON *root = cJSON_CreateObject();
	if(!root)
	{
		dzlog_error("wrong:%s\n",strerror(errno));
		return -3;
	}
	cJSON_AddNumberToObject(root,"temperature",temp);
	cJSON_AddNumberToObject(root,"time",tm);
	cJSON_AddNumberToObject(root,"smoke",smoke);


	char *s = cJSON_PrintUnformatted(root);
	strcpy(buf,s);
	cJSON_Delete(root);

}

